package cn.blnp.net.flowable.event.bound.compensation;

import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;

/**
 * <h3>边界事件-补偿边界事件</h3>
 *
 * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
 * @version 1.0
 * @since 2025/5/9 11:43
 */
@Slf4j
@SpringBootTest
public class BoundCompensationEvent {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;

    /**
     *  <p>
     *      补偿边界事件可以为所依附的流程活动附加补偿处理器（compensation handler），补偿处理器通过单向关联（association）连接补偿边界事件。补偿边界事件会在流程活
     *  动完成后根据实际情况触发，<b style="color:#1E90FF;">当补偿边界事件被触发时，执行它所连接的补偿处理器。</b>
     *  </p>
     *  <p>
     *      补偿边界事件必须通过直接引用设置唯一的补偿处理器。如果要通过一个活动补偿另一个活动的影响，可以将该活动的isForCompensation属性值设置为true，声明其为补偿处理器。
     *  补偿是通过活动附加的补偿边界事件所关联的补偿处理器完成的。需要注意的是，<b style="color:#1E90FF;">补偿处理器不允许存在流入或流出顺序流，它不在正常流程中执行，只在流
     *  程抛出补偿事件时执行。</b>
     *  </p>
     *  <p>
     *      补偿边界事件与其他边界事件的行为策略不同，<u>其他边界事件（如信号边界事件）在流程流转到其所依附的流程活动时即被激活，在流程活动结束时结束</u>，并且对应的事件订阅也会被取消，
     *   <b style="color:#1E90FF;">而补偿边界事件在其所依附流程活动结束后才被激活，并创建相应的边界事件订阅，在补偿边界事件触发或对应的流程实例结束时，事件订阅才会删除</b>。补偿边界事件
     *   一般在以下两种情况下被触发：
     *   <ol>
     *       <li>由补偿中间事件触发补偿边界事件</li>
     *       <li>事务子流程被取消，导致依附在事务子流程活动上的补偿边界事件被触发</li>
     *   </ol>
     *  </p>
     *  <p>
     *      补偿边界事件表示为依附在流程活动边界上、带有补偿事件图标的圆环。补偿事件图标是未填充的，表示捕获语义。元素示例如下所示：<br/>
     *      <img src="https://free4.yunpng.top/2025/05/09/681da228af49f.png" /><br/>
     *      <pre>
     *          {@code
     *              <process id="compensateBoundaryEventProcess">
     *                  <!-- 定义用户任务节点 -->
     *                  <userTask id="usertask1" name="审批"/>
     *                  <!-- 定义边界事件 -->
     *                  <boundaryEvent id="compensateBoundaryEvent1" name="补偿边界事件" attachedToRef="usertask1">
     *                      <compensateEventDefinition/>
     *                  </boundaryEvent>
     *                  <!-- 定义服务任务，作为补偿处理器 -->
     *                  <serviceTask id="serviceTask1" name="CompensationHandler" isForCompensation="true" flowable:class="**.**.**.****"/>
     *                  <!-- 定义关联 -->
     *                  <association id="association1" sourceRef="compensateBoundaryEvent1" targetRef="serviceTask1" associationDirection="None"/>
     *              </process>
     *          }
     *      </pre>
     *  </p><br/>
     *  <h2 style="color:red;">注意事项：</h2>
     *  <p>
     *      在Flowable中，当流程流转到依附边界事件的流程活动时，会向<u>ACT_RU_EVENT_SUBSCR</u>表中插入事件订阅数据，当其他边界事件所依附的活动完成后，这些事件订阅数据会被删除，
     *  但是补偿边界事件所产生的事件订阅数据不会被删除（直到补偿边界事件触发或流程实例结束）。这是因为即使流程活动完成了，依附的补偿事件仍有可能被触发。补偿边界事件使用时遵循以下规则：
     *  <ul>
     *      <li>当补偿被触发时，所有已成功完成的活动上附加的补偿边界事件对应的补偿处理器将被调用，如果补偿边界事件所依附的活动尚未产生历史任务，则不会被触发；</li>
     *      <li>如果补偿边界事件依附在多实例活动上，则会为每个实例创建补偿事件订阅，补偿边界事件被触发的次数与依附活动的循环多实例活动的成功完成次数相等；</li>
     *      <li>如果流程实例结束，则订阅的补偿事件都会结束；</li>
     *      <li>补偿边界事件不支持依附在内嵌子流程中。</li>
     *  </ul>
     *  </p>
     **/
    @Test
    public void test() {

    }
}
